package com.cloud2eye.auth.controller;

import com.alibaba.fastjson.JSONObject;

import com.cloud2eye.auth.AuthenticationRequest;
import com.cloud2eye.auth.jwt.CommonUtil;
import com.cloud2eye.auth.jwt.TokenAuth;
import com.cloud2eye.auth.service.UserService;
import com.cloud2eye.base.http.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class AuthController {

    @Value("${jwt.header}")
    private String tokenHeader;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenAuth tokenAuth;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private UserService userService;

    @PostMapping(value = "${jwt.route.authentication.path}")
    public Result createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest, HttpServletRequest rst) throws AuthenticationException {
        final Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        authenticationRequest.getUsername(),
                        authenticationRequest.getPassword()
                )
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);

        // Reload password post-security so we can generate token
        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());



        final String ip = CommonUtil.getIpAddr(rst);

        final String token = tokenAuth.generateToken(userDetails, ip);

        userService.updateToken(userDetails.getUsername(),token);

//        log.info("{} from {} get the token {}", authenticationRequest.getUsername(), ip, token);
        // Return the token
        JSONObject result = new JSONObject();
        result.put("token", token);
        return new Result().success(result);
    }

    @GetMapping(value = {"/", "/aoms"})
    public Map index(HttpServletRequest request) {
        Map map = new HashMap<>();
        map.put("status", "OK");
        map.put("message", "Welcome, no Auth");
        return map;
    }

    @GetMapping(value = {"/aoms/user"})
    public Map userTest(HttpServletRequest request) {
        String authToken = request.getHeader(this.tokenHeader);
        String username = tokenAuth.getUsernameFromToken(authToken);

        Map map = new HashMap<>();
        map.put("status", "OK");
        map.put("message", "Welcome, " + username);
        map.put("ip", tokenAuth.getIPfromToken(authToken));
        return map;
    }

    @GetMapping(value = {"/aoms/admin"})
    public Map adminTest(HttpServletRequest request) {
        String authToken = request.getHeader(this.tokenHeader);
        String username = tokenAuth.getUsernameFromToken(authToken);

        Map map = new HashMap<>();
        map.put("status", "OK");
        map.put("message", "Admin, Welcome, " + username);
        map.put("ip", tokenAuth.getIPfromToken(authToken));
        return map;
    }
}
